package com.logger;

import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.fmk.utils.RegExpUtils;
import com.fmk.utils.StringUtils;

public class LogTransaction {
    private Date           openDateTime;

    private Date           closeDateTime;
    private long           id;
    private List<LogQuery> queries;
    private final LogFile  logFile;
    private Boolean        commit;
    private String         msgError;

    LogTransaction(final LogFile logFile) {
        this.logFile = logFile;
    }

    public Date getOpenDateTime() {
        return this.openDateTime;
    }

    public void setOpenDateTime(final Date openDateTime) {
        this.openDateTime = openDateTime;
    }

    public Date getCloseDateTime() {
        return this.closeDateTime;
    }

    public void setCloseDateTime(final String line) {
        this.closeDateTime = LogQuery.setDateTime(line);
    }

    public void setCloseDateTime(final Date closeDateTime) {
        this.closeDateTime = closeDateTime;
    }

    public long getId() {
        return this.id;
    }

    public void setId(final long id) {
        this.id = id;
    }

    public List<LogQuery> getQueries() {
        if (this.queries == null) {
            this.queries = new ArrayList<LogQuery>() {
                /**
                 *
                 */
                private static final long serialVersionUID = 1L;

                @Override
                public String toString() {
                    final StringBuilder sb = new StringBuilder();
                    for (final LogQuery logQuery : this) {
                        sb.append(StringUtils.Constants.CRLF);
                        sb.append("        .");
                        sb.append(logQuery);
                    }
                    return super.toString();
                }
            };
        }
        return this.queries;
    }

    public void setQueries(final List<LogQuery> queries) {
        this.queries = queries;
    }

    public LogFile getLogFile() {
        return this.logFile;
    }

    public boolean isInitialized() {
        return this.openDateTime != null;
    }

    public LogTransaction init(final String line) {
        if (line.contains("Begin transaction")) {
            this.openDateTime = LogQuery.setDateTime(line);
            this.id = LogTransaction.setId(line);
            if (this.logFile.getSessionId() == null) {
                final String setSessionId = LogTransaction.setSessionId(line);
                this.logFile.setSessionId(setSessionId);
            }
            this.logFile.getListLogTransaction().add(this);
            return this;
        }
        return null;
    }

    public static long setId(final String line) {
        final String replacement = "";
        String newLine = line.replaceFirst(RegExpUtils.Constants.REGX_TRANSACTION_ID_BEGIN, replacement);
        newLine = newLine.replaceFirst(RegExpUtils.Constants.REGX_TRANSACTION_X_END, replacement);
        return Long.parseLong(newLine);
    }

    public static String setSessionId(final String line) {
        final String replacement = "";
        String newLine = line.replaceFirst(RegExpUtils.Constants.REGX_TRANSACTION_SESSION_ID_BEGIN, replacement);
        newLine = newLine.replaceFirst(RegExpUtils.Constants.REGX_TRANSACTION_X_END, replacement);
        return newLine;
    }

    public Boolean getCommit() {
        return this.commit;
    }

    public void setCommit(final Boolean commit) {
        this.commit = commit;
    }

    public static boolean isTransaction(final String line) {
        final String _regularExp = RegExpUtils.Constants.REGX_BEGIN_COMMIT_ROLLBACK_TRANSACTION;
        return RegExpUtils.isMatchFound(line, _regularExp);
    }

    public static boolean isCommitTransaction(final String line) {
        final String _regularExp = RegExpUtils.Constants.REGX_COMMIT_TRANSACTION;
        return RegExpUtils.isMatchFound(line, _regularExp);
    }

    public static boolean isRollBackTransaction(final String line) {
        final String _regularExp = RegExpUtils.Constants.REGX_ROLL_BACK_TRANSACTION;
        return RegExpUtils.isMatchFound(line, _regularExp);
    }

    public String getMsgError() {
        return this.msgError;
    }

    public void setMsgError(final String msgError) {
        this.msgError = msgError;
    }

    @Override
    public String toString() {
        String openDate = "";
        String closeDate = "";
        String elapsedTime = "";
        {
            final SimpleDateFormat parser = new SimpleDateFormat("HH:mm:ss");
            final ParsePosition pos = new ParsePosition(0);
            pos.setIndex(0);
            openDate = parser.format(this.openDateTime);
            if (this.closeDateTime != null) {
                closeDate = parser.format(this.closeDateTime);
                elapsedTime = Double.toString((this.closeDateTime.getTime() - this.openDateTime.getTime()) / 1000);
            }
        }
        final StringBuilder sb = new StringBuilder();
        sb.append("ID[");
        sb.append(this.id);
        sb.append("], FROM[");
        sb.append(openDate);
        sb.append("] TO[");
        sb.append(closeDate);
        sb.append("], [");
        sb.append(elapsedTime);
        sb.append("s], [");
        sb.append(this.commit == null ? "ERROR" : this.commit ? "COMMIT" : "ROLLBACK");
        sb.append("]");
        sb.append(StringUtils.Constants.CRLF);
        return sb.toString();
    }
}
